package com.changgou.oauth.service;

import com.changgou.oauth.util.AuthToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @program: changgou_parent
 * @author: zhanzhewan
 * @create: 2020-03-30 15:50
 **/
@Service
public class AuthServiceiml implements AuthService {


    @Autowired
    RestTemplate restTemplate;

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Value("${auth.clientId}")
    private String clientId;

    @Value("${auth.clientSecret}")
    private String clentIdSecret;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Value("${auth.ttl}")
    private long ttl;


    @Override
    public AuthToken token(String username, String password) {
        ServiceInstance choose = loadBalancerClient.choose("user-auth");
        // 获得host和port
        URI uri = choose.getUri();
        // 拼接成完整的url
        String uRL = uri + "/oauth/token";


        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
        body.add("username",username);
        body.add("password",password);
        body.add("grant_type","password");

        LinkedMultiValueMap<String, String> header = new LinkedMultiValueMap<>();
        header.add("Authorization", getHttpBasic(clientId, clentIdSecret));

        HttpEntity<MultiValueMap<String, String>> aa = new HttpEntity<>(body,header);
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
            @Override
            public void handleError(ClientHttpResponse response) throws IOException {
                if(response.getRawStatusCode() !=400 && response.getRawStatusCode() != 401){
                    super.handleError(response);
                }
            }
        });


        ResponseEntity<Map> exchange = restTemplate.exchange(uRL, HttpMethod.POST, aa, Map.class);
        //封装结果
        Map map = exchange.getBody();
        AuthToken authToken = new AuthToken();
        authToken.setAccessToken( (String) map.get("access_token"));
        authToken.setRefreshToken((String) map.get("refresh_token"));
        authToken.setJti((String) map.get("jti"));

        // 存入redis  将jwt存入redis 将jti作为key jwt作为value
        stringRedisTemplate.boundValueOps(authToken.getJti()).set(authToken.getAccessToken(),ttl, TimeUnit.SECONDS);

        return authToken;
    }

    private String getHttpBasic(String clientId, String clentIdSecret){
        String value = clientId+":"+clentIdSecret;
        byte[] encode = Base64Utils.encode(value.getBytes());
        return "Basic "+ new String(encode);
    }
}
